package com.seo.utils.alipay;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Component;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradeAppPayModel;
import com.alipay.api.domain.AlipayTradeWapPayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.internal.util.json.JSONWriter;
import com.alipay.api.request.AlipayTradeAppPayRequest;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.request.AlipayTradeWapPayRequest;
import com.alipay.api.response.AlipayTradeAppPayResponse;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.alipay.api.response.AlipayTradeWapPayResponse;
import com.seo.function.FunctionT1R;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class AlipayUtil {

	private Map<String, FunctionT1R<Map<String, String>, String>> channels = new HashMap<>();

	@PostConstruct
	public void init() {
		channels.put("page", this::alipayPage);
		channels.put("wap", this::alipayWap);
		channels.put("app", this::alipayApp);
	}

	public FunctionT1R<Map<String, String>, String> get(String key) {
		return channels.get(key);
	}

	public String alipayPage(Map<String, String> params) {
		String url = null;

		AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
		request.setReturnUrl(params.get("returnUrl"));
		request.setNotifyUrl(params.get("notifyUrl"));
		AlipayTradePagePayModel model = new AlipayTradePagePayModel();
		// 封装参数
		model.setOutTradeNo(params.get("outTradeNo"));
		model.setSubject(params.get("subject"));
		model.setTotalAmount(params.get("totalAmount"));
		model.setBody(params.get("body"));
		model.setTimeoutExpress(params.get("timeOutExpress"));
		model.setProductCode("FAST_INSTANT_TRADE_PAY");
		if (params.containsKey("qrPayMode")) {
			model.setQrPayMode(params.get("qrPayMode"));
		}
		if (params.containsKey("qrcodeWidth")) {
			model.setQrcodeWidth(Integer.valueOf(params.get("qrcodeWidth")));
		}
		request.setBizContent(new JSONWriter().write(model, true));

		AlipayClient alipayClient = null;
		if (params.containsKey("signType")) {
			alipayClient = new DefaultAlipayClient(params.get("gateWayUrl"), params.get("appId"),
					params.get("appPrivateKey"), "json", params.get("charset"), params.get("alipayPublicKey"),
					params.get("signType"));
		} else {
			alipayClient = new DefaultAlipayClient(params.get("gateWayUrl"), params.get("appId"),
					params.get("appPrivateKey"), "json", params.get("charset"), params.get("alipayPublicKey"));
		}

		AlipayTradePagePayResponse response = null;
		try {
			response = alipayClient.pageExecute(request);
		} catch (AlipayApiException e) {
			log.info("调用支付异常：[{}]", e);
		}
		if (response != null) {
			url = response.getBody();
		}

		return url;
	}

	public String alipayWap(Map<String, String> params) {
		String url = null;

		AlipayTradeWapPayRequest request = new AlipayTradeWapPayRequest();
		request.setReturnUrl(params.get("returnUrl"));
		request.setNotifyUrl(params.get("notifyUrl"));
		AlipayTradeWapPayModel model = new AlipayTradeWapPayModel();
		// 封装参数
		model.setOutTradeNo(params.get("outTradeNo"));
		model.setSubject(params.get("subject"));
		model.setTotalAmount(params.get("totalAmount"));
		model.setBody(params.get("body"));
		model.setTimeoutExpress(params.get("timeOutExpress"));
		model.setProductCode(params.get("sellerId"));
		request.setBizContent(new JSONWriter().write(model, true));
		AlipayClient alipayClient = null;
		if (params.containsKey("signType")) {
			alipayClient = new DefaultAlipayClient(params.get("gateWayUrl"), params.get("appId"),
					params.get("appPrivateKey"), "json", params.get("charset"), params.get("alipayPublicKey"),
					params.get("signType"));
		} else {
			alipayClient = new DefaultAlipayClient(params.get("gateWayUrl"), params.get("appId"),
					params.get("appPrivateKey"), "json", params.get("charset"), params.get("alipayPublicKey"));
		}

		AlipayTradeWapPayResponse response = null;
		try {
			response = alipayClient.pageExecute(request);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		if (response != null) {
			url = response.getBody();
		}

		return url;
	}

	public String alipayApp(Map<String, String> params) {
		String url = null;
		AlipayTradeAppPayRequest request = new AlipayTradeAppPayRequest();
		request.setReturnUrl(params.get("returnUrl"));
		request.setNotifyUrl(params.get("notifyUrl"));
		AlipayTradeAppPayModel model = new AlipayTradeAppPayModel();
		// 封装参数
		model.setOutTradeNo(params.get("outTradeNo"));
		model.setSubject(params.get("subject"));
		model.setTotalAmount(params.get("totalAmount"));
		model.setBody(params.get("body"));
		model.setTimeoutExpress(params.get("timeOutExpress"));
		model.setProductCode(params.get("sellerId"));
		model.setProductCode("QUICK_MSECURITY_PAY");

		request.setBizContent(new JSONWriter().write(model, true));
		AlipayClient alipayClient = new DefaultAlipayClient(params.get("gateWayUrl"), params.get("appId"),
				params.get("appPrivateKey"), "json", params.get("charset"), params.get("alipayPublicKey"),
				params.get("signType"));
		AlipayTradeAppPayResponse response = null;
		try {
			response = alipayClient.sdkExecute(request);
		} catch (AlipayApiException e) {
			e.printStackTrace();
		}
		if (response != null) {
			url = response.getBody();
		}

		return url;
	}

	public LightPayCashierAlipay getNotifyResult(Map<String, String> params, AlipayConfig ac)
			throws AlipayApiException {

		return getNotifyResult(params, ac, null);
	}

	public LightPayCashierAlipay getNotifyResult(Map<String, String> params, AlipayConfig ac, List<String> excludeKeys)
			throws AlipayApiException {

		LightPayCashierAlipay result = new LightPayCashierAlipay();
		if (excludeKeys != null && excludeKeys.size() > 0) {
			result.setUdfParams(new HashMap<String, String>());
			for (String key : excludeKeys) {
				if (!StringUtils.isEmpty(key)) {
					result.getUdfParams().put(key, params.remove(key));
				}
			}
		}
		log.info("返回参数-[{}]-支付宝公钥-[{}]-charset-[{}]-signtype-[{}]", params, ac.getAlipayPublicKey(), ac.getCharset(),
				ac.getSignType());
		try {

			if (!rsaCheckV1(params, ac.getAlipayPublicKey(), ac.getCharset(), ac.getSignType())) {
				throw new AlipayApiException("验签失败，请检查支付宝公钥是否配置正确！");
			}
		} catch (AlipayApiException e) {
			log.error("签名失败-[{}]", e);
			throw e;
		}
		result.setResultType(LightPayCashierAlipay.TYPE_NOTIFY);
		result.setOutTradeNo(params.get("out_trade_no"));
		result.setTradeNo(params.get("trade_no"));
		result.setTotalAmount(params.get("total_amount"));
		result.setSellerId(params.get("seller_id"));
		result.setTradeStatus(params.get("trade_status"));
		result.setRefundFee(params.get("refund_fee"));
		result.setGmtCreate(params.get("gmt_create"));
		result.setGmtPayment(params.get("gmt_payment"));
		result.setGmtClose(params.get("gmt_close"));
		result.setGmtRefund(params.get("gmt_refund"));
		result.setBuyerId(params.get("buyer_id"));
		return result;
	}

	public LightPayCashierAlipay getReturnResult(Map<String, String> params, AlipayConfig ac)
			throws AlipayApiException {

		return getReturnResult(params, ac, null);
	}

	public LightPayCashierAlipay getReturnResult(Map<String, String> params, AlipayConfig ac, List<String> excludeKeys)
			throws AlipayApiException {

		LightPayCashierAlipay result = new LightPayCashierAlipay();
		if (excludeKeys != null && excludeKeys.size() > 0) {
			result.setUdfParams(new HashMap<String, String>());
			for (String key : excludeKeys) {
				if (!StringUtils.isEmpty(key)) {
					result.getUdfParams().put(key, params.remove(key));
				}
			}
		}
		try {
			if (!rsaCheckV1(params, ac.getAlipayPublicKey(), ac.getCharset(), ac.getSignType())) {
				throw new AlipayApiException("验签失败，请检查支付宝公钥是否配置正确！");
			}
		} catch (AlipayApiException e) {
			throw new AlipayApiException("验签失败，请检查支付宝公钥是否配置正确！");
		}
		result.setResultType(LightPayCashierAlipay.TYPE_RETURN);
		result.setOutTradeNo(params.get("out_trade_no"));
		result.setTradeNo(params.get("trade_no"));
		result.setTotalAmount(params.get("total_amount"));
		result.setSellerId(params.get("seller_id"));
		return result;
	}

	public boolean rsaCheckV1(Map<String, String> params, String publicKey, String charset, String signType)
			throws AlipayApiException {
		String sign = params.get("sign");
		String content = AlipaySignature.getSignCheckContentV1(params);
		log.info("原始签名-[{}]-拼接参数-[{}]", sign, content);
		return AlipaySignature.rsaCheck(content, sign, publicKey, charset, signType);
	}

}
